package proj2;

import javax.security.auth.Subject;

public class ClauseForm extends FOLParser {

	/**
	 * @author monica
	 * @param String
	 * @return int [] this method takes an expression in the form of a string or
	 *         substring and returns the index of the term where the 1st cell is
	 *         the start and 2nd is end index
	 */
	public static int[] indexof1stop(String x) {
		int[] index = { 0, 0 };
		int open = 0;
		int close = 0;
		for (int i = 0; i < x.length(); i++) {
			if (x.charAt(i) == '(') {
				if (open == close) {
					index[0] = i;
					// System.out.println("la2et(");
				}
				open++;
			}
			if (x.charAt(i) == ')') {
				close++;
				// System.out.println("la2eit )");
				if (close == open) {
					index[1] = i + 1;
					// System.out.println("la2eit term");
					break;
				}
			}
		}
		return index;
	}

	/**
	 * @author monica
	 * @param string
	 * @return string this method takes the expression in the form of a string
	 *         and removes the EQV to fulfill the 1st step of CF this method is
	 *         implemented by recursion;
	 */
	public static String EQVrem(String s) {// FOLParser p) {

		// String changetos = p.expression.listify();
		// s = "( EQV ( AND x y ) ( OR z w ) )";
		String end = s;
		if (s.contains("EQV")) {
			int eqvindex = s.indexOf("( EQV");
			String start = s.substring(0, eqvindex + 1);
			int endeqindex = eqvindex + 4;
			String rest = s.substring(endeqindex);
			int[] op1i = indexof1stop(rest);

			String op1 = rest.substring(op1i[0], op1i[1]);
			rest = rest.substring(op1i[1]);

			int[] op2i = indexof1stop(rest);
			String op2 = rest.substring(op2i[0], op2i[1]);
			rest = "( " + rest.substring(op2i[1] + 2);

			String toadd1 = "( IMP " + op1 + " " + op2 + " )";
			String toadd2 = "( IMP " + op2 + " " + op1 + " )";
			String toadd = " AND " + toadd1 + " " + toadd2;

			end = start + " (" + toadd + " ) " + rest + " )";
			end = end.replace("  ", " ");
			end = end.replace("( )", "");

			end = end.replace("()", "");

			// p=new FOLParser(end);
			// System.out.println(p.expression.listify());
			EQVrem(end);
		} else {
			// IMPrem(end);
			System.out.println("equiv. removal: " + end);
			System.out.println("equiv remove is satisfied now ;)");
		}
		return end;
	}

	/**
	 * @author monica
	 * @param string
	 * @return string this method takes the expression in the form of a string
	 *         and removes the IMP to fulfill the 2st step of CF this method is
	 *         implemented by recursion;
	 */
	public static String IMPrem(String s) {

		String end = s;
		if (s.contains("IMP")) {
			int eqvindex = s.indexOf("( IMP");
			String start = s.substring(0, eqvindex);
			int endeqindex = eqvindex + 4;
			String rest = s.substring(endeqindex);
			int[] op1i = indexof1stop(rest);

			String op1 = rest.substring(op1i[0], op1i[1]);
			rest = rest.substring(op1i[1]);

			int[] op2i = indexof1stop(rest);
			String op2 = rest.substring(op2i[0], op2i[1]);
			rest = "( " + rest.substring(op2i[1] + 2);

			String toadd1 = "( NOT " + op1 + " ) ";
			String toadd = "( OR " + toadd1 + " " + op2 + " )";

			end = start + toadd + rest + " )";
			end = end.replace("  ", " ");
			end = end.replace("( )", "");

			end = end.replace("()", "");

			// p=new FOLParser(end);
			// System.out.println(p.expression.listify());
			IMPrem(end);
		} else {
			System.out.println("IMP. removal: " + end);
			System.out.println("IMP remove is satisfied now ;)");
		}
		return end;
	}

	/**
	 * @author monica
	 * @param string
	 * @return string this method handels the not as it pushes it inwards, if we
	 *         have 2 nots then they are canceled, ALL changes to EXT, OR and
	 *         ANd are handeled a problem here is that it works for just 1st not
	 *         and can't handle the rest of the sentence (to be modified later)
	 *         a solution idea to save all partitions in an array and handle
	 *         each alone then concatinate
	 */
	public static String Notin(String s) {
		// think of putting the Nots in an array and loop over every expression
		// to change it then concatinate all
		// s = " ( NOT ( EXT ( x ) ) ) ";
		String end = s;
		String rest = s;
		for (int x = 0; x < s.length(); x++) {
			// int z = 0;
			String op1 = "";
			if (rest.contains("NOT")) {

				int eqvindex = rest.indexOf("( NOT");

				String start = s.substring(0, eqvindex);
				int endeqindex = eqvindex + 4;
				rest = rest.substring(endeqindex + 2);
				// System.out.println("start: " + start);
				// System.out.println("rest: " + rest);
				int[] op1i = indexof1stop(rest);
				op1 = rest.substring(op1i[0], op1i[1]);
				rest = rest.substring(op1i[1]);
				// System.out.println(op1);

				if (op1.contains("AND")) {
					int afterand = op1.indexOf("AND") + 3;
					String andop1 = op1.substring(afterand);
					// System.out.println(afterand);
					// System.out.println(andop1);
					int[] op11i = indexof1stop(andop1);
					// System.out.println(op11i[0] + " " + op11i[1]);
					String op11 = andop1.substring(op11i[0], op11i[1]);
					// System.out.println("op11" + op11);
					andop1 = andop1.substring(op11i[1]);
					int[] op2i = indexof1stop(andop1);
					String op2 = andop1.substring(op2i[0], op2i[1]);
					// op1=op1.replace("AND", "OR");
					op11 = "( NOT " + op11 + " )";
					op2 = "( NOT " + op2 + " )";
					op1 = "( OR " + op11 + op2 + " )";
					// System.out.println(op1);
					end = start + op1 + rest;
					op1="";
					//System.out.println("la2 henaaaa");
				} else {

					if (op1.contains("OR")) {
						int afterand = op1.indexOf("OR") + 3;
						String andop1 = op1.substring(afterand);
						// System.out.println(afterand);
						// System.out.println(andop1);
						int[] op11i = indexof1stop(andop1);
						// System.out.println(op11i[0] + " " + op11i[1]);
						String op11 = andop1.substring(op11i[0], op11i[1]);
						// System.out.println("op11" + op11);
						andop1 = andop1.substring(op11i[1]);
						int[] op2i = indexof1stop(andop1);
						String op2 = andop1.substring(op2i[0], op2i[1]);
						// op1=op1.replace("AND", "OR");
						op11 = "( NOT " + op11 + " )";
						op2 = "( NOT " + op2 + " )";
						op1 = "( AND " + op11 + op2 + " )";
						// System.out.println(op1);
						end = start + op1 + rest;
					} else {
						if (op1.contains("ALL")) {
							// String op2 = s.substring(rest.indexOf(op1)+1,
							// op1.length()-1);
							String op2 = op1.replace(" ALL", " ( EXT");

							// rest=rest.substring(rest.indexOf("ALL")+3);
							start = end.substring(0, s.indexOf(op1) - 4);
							end = start + op2 + rest;
							//System.out.println(start+"2aaaaaaah");
							// end = start + rest;
						} else {
							if (op1.contains("EXT")) {
								op1 = op1.replace(" EXT", " ( ALL");
								end = start + op1 + rest;
								
							}
						}
						// return end;
					}
				}
				if (s.contains("NOT ( NOT")) {
					s = s.replace("NOT ( NOT", "");
					rest = rest.replace("NOT ( NOT", "");
					op1 = op1.replace("NOT ( NOT", "");
					op1 = op1.replace(" NOT", "");
					end = start + op1 + rest;
					// System.out.println(op1);
					// System.out.println("if");
				}

				// Notin(rest);
				// System.out.println(end);
			}
		}
		System.out.println(end);
		return end;
	}

	/**
	 * 
	 * @author monica
	 * @param s
	 * @return this method is to ignore the ALL
	 */
	public static String ALLrem(String s) {
		String end = s;
		if (s.contains("ALL")) {
			int i = s.indexOf("ALL") - 1;
			String start = s.substring(0, i);
			String toalter = s.substring(i + 4);
			int[] op = indexof1stop(toalter);
			// String oprem=toalter.substring(op[0],op[1]);
			toalter = toalter.substring(op[1]);
			end = start + toalter;
			ALLrem(end);

		}
		// end = s.replace(" ALL", "");
		else {
			System.out.println(end);
			// end.replace("( )", "");
		}
		return end;
	}

	// /////////
	public static void helpstand(String s) {

	}

	public static String stand(String s, int i) {
		String end = s;
		if (s.contains("ALL")) {
			int index = s.indexOf("ALL");
			String start = s.substring(0, index);
			String rest = s.substring(index + 4);
			int[] op = indexof1stop(rest);
			rest = rest.substring(op[1]);
			String op1 = rest.substring(op[0], op[1]);
			for (int x = 0; x < op1.length(); x++) {
				String change = "" + op1.charAt(x);
				if (op1.charAt(x) == ' ' || op1.charAt(x) == '('
						|| op1.charAt(x) == ')') {
					change = "" + op1.charAt(x) + i;

				}
				op1 = op1.replace("" + op1.charAt(x), change);
			}
			i++;
			end = start + op1 + rest;
			// stand(end,i);

		}
		System.out.println(end);
		// i=i++;

		return end;
	}

	// ////////////

	/**
	 * @author monica
	 * @param string
	 *            this method calls the methods of cf steps to get the final
	 *            Clause form of an expression
	 * @return
	 */
	public static String clauseform(String s) {
		String clause;
		clause = EQVrem(s);
		clause = IMPrem(clause);
		return clause;
	}

	public static void main(String[] args) {
		// FOLParser fol = new FOLParser("b AND c EQV y ");
		// EQVrem("( EQV ( AND ( x ) ( y ) ) ( OR ( z ) ( w ) ) ( EQV ( c ) ( d ) ) ( EQV ( c ) ( d ) ) )");
		// IMPrem("( IMP ( x )( IMP ( a ) ( AND ( c ) ( b ) ) ) )");
		// System.out.print("\nFOL Parsed: ");
		// System.out.println(fol.listify());
		Notin(" ( NOT ( OR ( x ) ( y ) ) ) ( NOT ( NOT ( c ) ) ) ( NOT ( ALL ( x y ) ) )");
		// stand("( ALL ( x )( a AND b ) ( ALL ( y ) ) )", 0);
		//Notin("( NOT ( NOT ( c ) ) )");
	}

}
